プログラミングやRPG(作るほう)が好きな人の日記
個人的な趣味(プログラミング、イラスト、電子回路)のページです。 自身のパソコンのやりすぎに対する管理の表の公開、 最近見ているアニメや映画と 買い物の簡易なリスト、 それから日記を掲載しています。日記が主体です。 |
ページが少しごちゃごちゃとしているため、このページの全体像をここに示します。
この表は、このウェブページの管理人のパソコンの使用時間を管理・制限するためのものです。
このようなプライベートなことを公開して、ちょっと恥ずかしいようなところもありますが、公開することでうまくいっているので良しとしています。
No. (ID) |
A1. 開始時 運動 |
A2. 勉 強 1問 |
A3. 終了時 運動 |
H1. 予定 作業内容 |
H2. 予定 作業詳細 判定×の理由 |
B.
実際 開始時刻 |
C. 予定 使用時間 (当日限度) |
D. 予定 終了時刻 |
E.
実際 終了時刻 |
F.
実際 使用時間 |
G1.
判定 ◎ 9分以下
○ 10分~19分 △ 20分~29分 × 30分以上 |
---|---|---|---|---|---|---|---|---|---|---|---|
ちょっとこの表の更新を停止します。 でもパソコンの起動時間は自動的に記録されているので、1日当たりどのくらいパソコンを使っていたのかは、 データから起こすことが可能です。 今は表が無くても、電源制御により、おおむね、1.5h区切りで作業できているし、夜11:00には終了できているので、大丈夫かなと思っています。 | |||||||||||
0438 | ○ | ||||||||||
15分以上別のこと: 夕食 | |||||||||||
0909 | 17:46 | 1:40 | 19:26 | 1:40 |
※この表の自動化の話をここに書きましたが、自動化をするヒマがないので、もともとのやり方で再開します。
(こういう管理が自分の頭の外にないと まともにやれないなんて、「松葉づえ」を手放せずに生きているようなものだな…)
ちょっと面白いことを書きますが、パソコンを起動して、1:30時間が経つと、自動的に「ラジオ体操第一」の動画がフルスクリーンで表示され、その動画が終わると、パソコンはシャットダウンされるように、システムを調整してあります。笑い話ではないんですが、それほど、PC作業にとって身体の運動は、必須なんです。
また、夜23時から、翌日正午までの間にパソコンが起動されると、自動的にシャットダウンされるようにもなっています。「夜更かししないこと」は世間でも良く知られている健康の条件です。そして、「午前中に PC 作業しないこと」というのは、私が最近知った新しい健康の秘訣です。それが良いな、具合が良いなと実際に思ったんです。
この表の意図:
多くの人はパソコンのやりすぎやネットゲームのやりすぎには困っていると 思います。
参考に言うと、この表を使う前の私は 1 回の PC 使用時間がノンストップで 17 時間というときもあったし、平均で言うと毎日 9 時間はやっていたと思います。
この表を使ってパソコンの使用時間を 事前に決めて、ネッ ト上に公開 することで、パソコンのやりすぎを防止できたら、と思います。
また、数年前から考えてきましたが、そういう徹夜とか長時間作業をするよ りも、昼間の短時間作業のほうが生産性は高いのではないかと思います。そういう意味でも期待しています。
※以前は NO PC WEEK と称してパソコンを使用しない期間を設けることでやりすぎに対処してきましたが、もっと具合の良い方法はないかと考え、この表を使うようになりました。
臨時お試し(2022年1月8日~)
最近、状況が以下のように少し変化していて…
…これまでのやり方だとうまくいかないところがあるので、お試しでやり方を少し変更します。
お試しで以下のようにします。
これがうまくいかない場合は、以上を取り消しします。
(「1.5h(または2.0h)ごとに区切り、」というのが難しいんじゃないかと思う…)
中途結果
記入の規則:
ちなみに、分単位で記録を取ったりして、だいぶマメに見えるかもしれませんが、Windows の日本語入力(MS-IME)で「いま」と入力し、 変換 キーを押さずに ↑ ボタンを押すと現在の時刻になります。道具の便利さが人をマメに見せるのかもしれません。
例外事項:
「スーパーPC WEEK」:
連休中(3連休以上)に、NO PC WEEK をオフにして好きなだけパソコンを使ってよいとする期間を、「NO PC WEEK」に対して「スーパーPC WEEK」と言う。
ただし以下の決まりを守ること。
なお、表の中央やや右寄りの「C. 予定 使用時間(当日限度)」列の "当日限度" には UNLOCK と記入する。
中途結果(2022/4):
(この記事は作成途中です)
現在固まってきた運用の内容をここにまとめます。
個人的ではありますが、自分にとって効果があると思っているものです。
ご参考になれば幸いです。
効果 大:
昼12時に電源供給が開始、夜11時に電源供給が終了するしくみ
電源オンオフタイマーを使用して、パソコンの電源タップへの電力の供給を制御します。
これにより、時間になるとマルチディスプレイの外付けの大きなディスプレイの電源が切れたり、オンされたりします。
パソコンの電源を入れた後、1.5Hで電源が切れる(休止状態になる)しくみ
1.5Hと1.5Hのあいだは15分以上別のことを行うルール
効果 中:
パソコン使用の前後に運動をする。
その他 続けていること:
パソコン使用の前に勉強の問題を1問解く
自分の家族にすすめたい方へ:
パソコンのやりすぎやネットゲームのやりすぎは社会問題にもなっているので、「うちの子についてなんとかしないと…」と思っている ご家族の方は多くいらっしゃると思います。
私の両親も過去に私について問題にしていました。学校へ行かず、毎日朝までパソコンに向かい、 悶々としていたんです。
この表はその家族が困っていたときから 30 年後に、私が自分で必要を感じて作ったものです。
私は今 一人暮らしをしていて、自分で生計を立てる中、パソコンにおぼれた生活をすると、生活がうまく回らなくなるんです。
具体的には、
これらを改善するために表を作りました。
でも、このような必要にせまられて「自分の動機で始めた場合」と、「人からすすめられて始めた場合」とでは、結果が異なると思いま す。
自分の切実な動機で始めたなら自分から進んでこの表を活用すると思いますが、外から押し付けられたものはなかなか定着しないもので す。
あまり適当なことは言えませんが、「中途結果」タブの中の青い部分で 書いたことは、本人にとって得になることなので、「ときどき休憩して、他のあの趣味やってみたらどうだ?」とか「ときどき休憩したほ うがプログラミングの質が上がるって話だぞ?」という形ですすめてみたらどうでしょうか。(それでも最終的には自立してもらうことは 必要だと思いますが)
私が両親を困らせていたときに、突然、外へ一人で出て行って、一人暮らしを始めたり、接客業を始めたり、いくつか資格取得したりと いろいろ行えた理由というのは、正直言ってわかりません。(※しかし途中で失業して2度、実家に戻ったことがあります。1 回目は 21 才くらいのときに 5 年間、2 回目は 35 才くらいのときに1年未満、実家にいて、何もしてなかったり働いたりしていました)
私が両親を困らせていたのは 16 才 ~ 20 才くらいの学生のころですが、そのころ家族と私自身と友人たちがみんなそれぞれ、私の生活について心配したり困ったり悩んだり、あの手この手を試したりしていました。そう いう煮詰まったような状況が運命をそのように(解決の方向へ)動かすのかもしれません。運命がどうの というのは変ですが、そのくらいのことしか言えません。何かしら取り組む必要があるということですかね。
この社会問題はクリアーすべきものみたいです。
日
付 (上ほど新しい) |
タイトル | 無料配信 配信日 |
公評価 | 私 評価 |
---|---|---|---|---|
2022/6/2~視聴中 | デスノート(リンクはYahoo GYAO で検索) 昔、「最近の週刊少年ジャンプはどうなのか」と、突然ジャンプを一冊買い、そのときたまたま同漫画の1話目を読みました。その後 数年後に友達に勧められて、面白くて単行本を全部買いました。
映画のほうも面白かったです。
2022年になって、同様に「最近のジャンプはどうなのか」と思って、手に取ってみてみると、なんか少女漫画みたいなのが2、3入っていて、少しびっくりしました。
聖闘士星矢今こそはばたけとか、お前はもう死んでいるとか、ボールは友達だとか、へのつっぱりはいらんですよ、とかそういう世界ではなくなっていた…。 |
毎日 | 4.7 | 4.4 |
2021/7/15~視聴中 | ドラゴンボール改(リンクは Yahoo GYAO で検索) 冒険・格闘技/1984年週刊少年ジャンプ/各話25分程度 |
・・・・金土日 | 4.8 | 4.5 |
このところ、Yahooの無料映画サービス「GYAO」で映画をいっぱい観ています。
映画の場合は公私それぞれ★ 3.5 以上で黄色塗りにします。★2.9以下は青塗りにします。
■■であれば公私ともに落第点。■■や■■であれば公私で意見が分かれている。■■であれば公私ともにGOOD。白塗りは可もなく不可もなく。
日
付 (上ほど新しい) |
タイトル | 無料配信 (日付まで) |
公評価 | 私 評価 |
---|---|---|---|---|
2022/6 | パッション(R15+)(リンクはGYAOで検索)
私のレビュータイトル:こういう映画もある。
まぁ、最初は、不思議な音楽とともに始まって、異色の映画を におわせている。
その通りで、この映画は途中からグラッとくる。 そのグラッと来たところも、まぁ、観ていられなくもない、、 グラッと来て、立ち直るのかどうかは観てのお楽しみかな。 サスペンス映画で、ノオミ・ラパス主演。
高めの評価になっていますが、同性愛と、ネガティブな内容で、その辺が苦手に思う人には合わないかも。
オススメ度:映画好きの人にオススメ |
7月4日(月) 23:59まで | 3.6 | 3.6 |
買い物も映画と同じく、公私それぞれ★ 3.5 以上で黄色塗りにします。★2.9以下は青塗りにします。 ■■であれば公私ともに落第点。■■や■■であれば公私で意見が分かれている。■■であれば公私ともにGOOD。白塗りは可もなく不可もなく。
日
付 (上ほど新しい) |
タイトル | 公評価 | 私 評価 |
---|---|---|---|
2022/6/20 | 水戸駅ビルの書店へぶらりと立ち寄り、「アセンブラ独習」という4cmくらいの厚さの分厚い本を買おうかと思ったけど、身体に悪そうだと思い、ためらっていたところ、近くに Django の本を見つけました。 昔友人から勧められて、ちょっといじったけど、挫折し、その後ずっと気になっていました。 せっかく教えてもらったのだし、活用しなくてはと思い、本を購入。 この Web ページを Django で作り直そうと計画したが、そもそも契約しているサーバーがこういうものをインストール出来るのかどうか不明であることに後から気が付いた! このサイトさんによると、 さくらインターネット(スタンダードプラン)は他のユーザとの共有サーバのためデーモンは禁止されており、runserverで立てたDjangoのプロセスは、ターミナルを閉じるとkillされてしまう。 ということだ。サイトさんではそこをなんとか動かすような裏技を紹介してくれているが、動作が重いらしい。 でも、こちらのサイトさんによると、さくら VPS なら Django アプリを公開できるらしいので、そっちに契約を変更すれば良さそうだ。月額もあまり変わらないし…でも契約更新したばかりだから。 この本には、作成した Django アプリを GitHub で公開する手順を紹介しているので、まずはそこからやれば良いかな。 |
3.8 | 未読 |
2022/6/19 | ダイソーでマネキンヘッドを買いました。600 円(税別)。 360 度、どの方向からも人間の顔を観察し、イラストのデッサンに役立てるためです。 「3Dのデッサン人形アプリ」を使えば、同じことが自由自在にできて楽しいんですが、昔ながらのレトロでアナログな方法のほうが、絵描きの楽しさをもっと十分に享受できると思います。 それはなぜなのかというと、3Dだと、自分の力じゃない誰でもできるという感じがするし、本物のマネキンなら自分の力で描くし、マネキンと自分との間に空気があり存在感があります。難しい話ですが焦点距離(焦点距離小:ペットの鼻デカ画像、焦点距離大:望遠カメラ)もソフトウェアによるものではなく、肉眼の中にある水晶体レンズの焦点距離となるので、見た目らしい描画を望める。そして現実の陰影もついています。3Dほど自由自在さはないけど、限られた条件(このマネキンが提供できるものの限り、女性タイプで細身のみとか)の中でいかに良いものを作り出すか、また、「限られた条件」というのはクリエイターの想像力をあふれさせる力がある(過去の性能の限られたファミコンとか)。 だから木でできた昔ながらの「デッサン人形」も良いものだと思っています。 |
不明 | 現在 未使用 |
47才、男、B型(BB)
電子機器の基板を製造する工場で、派遣で働いています。
プログラミングが好きで小学校5年生のころからずっと続けています。
ページ上にていろいろ才能(少々 粗削りな才能)を発揮していると思いますが、なるべく自 分だけで終わらないようにといつも思っています。
いろいろ厳しい考え方も持っていますが、厳しすぎないように周囲の人々とのバランスも考えていま す。
たとえば、著作権について私はだいぶ細かく考えていますが、私以外の人について 特に厳しく言ったり批判的に見たりはしません。
著作権は難しいし、ちょっとぐらい いいじゃないか、という人間らしい気持ちを肯定したいからです。
■趣味: プログラミング、ゲーム音楽を集めて聴く、イラストを描く、映画、アニメ、ガンプラ (興味の強い順)
■将来の夢は5つくらい持っていますが、生きてる間に実現できそうにありません。
■私が使っているペンネーム(ハンドルネーム)は新しい順に
ペ ンネーム(ハンドルネーム) | いつごろ | 場 所 |
---|---|---|
sankakkei、三角形(下のペンネームからの交代) NEW | 現在(少) | Yahoo Japan |
daikei、台形(本名の姓の頭文字がK、名がダイ~なので、ダイケイ) | 現在(少) | Yahoo Japan |
d_kawakawa | 現在(多) | どこでも |
cookiepurinman、cookiepudingman | ちょっと前 | |
かわ、kawa | 30年前 | パソコン通信 |
※基本的には d_kawakawa とお呼びください。
■勝手に Q&A
Q: サイトがゴチャゴチャしていて何が何だか。
A: 私が作る作品には「計画性」がなく、「思い付き」で後から次から次へと追加していくような作り方をしています。
そのため、わけわからない感じになっちゃってるかもしれません。
Q: サイト内の一部の表示が、壊れているみたいです。
A: 2021年9月に旧システムから新システムへ移行しました。
そのせいで、旧システムで使っていた機能の互換性が取れていません。
順次対応していますが、時間があまりないのでなかなか直しきれません。
Q: 昔進めていたコンテンツは、途中のままで、終わっているんですか?
下図のように昔進めていたいろいろなコンテンツがありますが、
これら全部「保留」のつもりでいます。
なんか、いろいろ必要なことが別にあって、それぞれ「待ち行列」みたいに並んでいます。
たとえば、今やっている「RPGのメニュー」は、上図の「SVC」と関係があって、つまり、RPGの基本の部分にはメニューがあり、そのメニューを先にクリアしないと「SVC」を作る意味がない気がするんです。
DRAM については1つ難問があって、回路自体はそんなに問題じゃない気がしますが、回路を人々に教えようとするとき、どのマイコンを使うのかが問題で、誰でも手に入り、誰でも実験でき…と考えると、どのマイコンを採用すべきか。また、実験するために安価なオシロスコープはどれだろう、なんて探し始めて、その辺で止まっています。
Q: RPG を作ろうとしているようですが、素人の域を越えられますか?(メジャーになれますか)
素人の域でゴネゴネやっている感じがしていて、果たして上に上がれるのかどうか。
そんなことを言っている私は、つまり上に上がろうとしているってことですね。
RPG のルーツを探ったり、古い RPG の面白さのエッセンスを探し出したりと、「真髄」、「要点」、を研究したり、「実体験をした人にしか出せない言葉がある」とか、INTKSBFS といった 面白い RPG のための「くしざし(頭文字を並べたもの)」も作ったりしているので、たぶん人の心に届く RPG を作る下地はあるんじゃないかと思います。
「大作を作ろうとする人は失敗する」という仮定があって、「実体験をもとに、できる範囲で、規模の小さめの RPG を作る」という方針が、素人の域を超えられるかどうかの一つのカギだと思っています。「小中高校生のため、その両親とのあいだや、友達同士をつなげるような思い出になるようなもの」という利己的ではない利他的なスタイルが絶対に必要だ、という考え方も、そのカギの一つです。
越えられませんと言っているようじゃ、越えられませんので、越えられますとはっきりと言っておきましょう。それだけの年数と研究、倫理観(開発者の気持ちはこうあるべきだ等)を重ねていますから。
でも人間の1つの幸せとして、たった一人の幼い子供さんを、私の作品で楽しませることさえできれば、それで良いんじゃないかという考え方も持っています。そういう意味では超える気がありません(越えられません)ということになるのかな。
どっちなんだよ。青く塗った部分が良いなと思います。
素人の域を越えてメジャーになったって、消費者たちから文句の応酬を食らっているのであれば(アマゾンの有名ゲームタイトルの言われようと来たら)、それは幸せなんでしょうか。
■私への連絡手段:
ごくまれにしかツイートしませんが、私の twitter アカウントはこちらです。
https://twitter.com/cookiepudingman
何かメッセージをくれれば、返事すると思います。
返事がないときはメッセージに気付いていないんだと思います。そのときはすみません。
<<重要>>
それから 2020 年の年末ごろに携帯電話を紛失した関係で、知り合いの電話番号がすべてわからなくなりました。
その後 携帯電話は見つかりましたが、電話帳データを新しい携帯電話へ移動することが、ちょっと面倒で電話帳の復帰をしていません。
なおかつ、最近の詐欺電話の対策として、番号非通知や「電話帳に載っていない電話番号」からの着信には基本的に出ないことにしています。
なので、「知り合いからの着信に出ない」という結果になっていると思います。
「電話帳データ復帰せんかーい!!」って話ですが、とにかく面倒は苦手すぎな性格なので、まぁ運が良ければまた。って感じ。
すまん。べつに嫌いってわけじゃなくて、なんとかなるだろうって思ってるだけです。
■管理人用:
PC-9801 臨時特設ページを開く …特設ページ作りましたが、更新は止まっています。
…国家検定の電子機器組立て2級の暗記ツール(基板上配置)です。1級でも役立つと思います。
このサイトで最も興味を引く部分: (そのつもり)
最近、私は個人的に、「RPG のコマンドメニュー部分のプログラム」を、中高生向けに、ステップバイステップ方式で教えようとしています。
ステップ同士のプログラム上の変化をマーキングして表示したり、バルーンメッセージを使って説明を付けたりと、いろいろ工夫をしていますが、はっきりいってわかりにくいんじゃないかと思っています。
RPGメニューを作る1 基本のプログラムからはじめて、サブメニューを表示するまで Step 1~8 |
RPGメニューを作る2(記事としては4) メニューの項目に、付加情報(装備中のe記号や、店の価格)を表示。 Step 9、10、11 |
RPGメニューを作る3(記事としては5) メニューの項目を段組表示する Step 12、13 |
2022/8/26(金)に Yahoo オークションで私が入札した、Windows 3.1 ですが、見事競り落とせました。
おめでとう。落札価格は 1 万円でした。(Windows 3.1 発売当時の定価はだいたい 2 万円だったそうです)
でもまた、入札者私一人だったので、誰とも競っていません。
Windows 3.1 っていつ頃登場したんだっけ…
Wikipedia によると、1991 年。
今から 31 年前ですねぇ。
31 年前のフロッピーディスク…大丈夫かな。
Windows 3.1 を買う理由は、「はじめて読む486」(リンクは Amazon 当該ページ)の一部のテストプログラムが、Windows 3.1 用だからです。
それを試すためには、買う必要があると。それだけ。
そして、Windows 3.1 をどこにインストールするのかというと、おもに 「Neko Project」という PC-9801 エミュレーター上にインストールしようと考えています。
Excel の図形を VBA を使って、.js テキストファイルへ書き出して、JavaScript でその図形を表示する…、というようなことに取り組んでいます。。
前回記事で書いたように、一部の図形(楕円など)はそのままでは 3D 計算できない情報で構成されているので、その情報をベジェ曲線データへ変換する必要があります。
で、実際にベジェ曲線を 3D 回転させようというとき、「配列」などどんなデータ形式なら、扱いやすいのか確認するために、JavaScript での 3D 回転のサンプルを作りました。
前々からこの手の 3D 回転はやってきましたが、改めて、ということで…
こういう画面を見ると、ある人は、「WebGL を使ってるのかな」と思うだろうし、ある人は「難しそうだ」と思うでしょう。
でもこれは WebGL のような難しいものは使っていないし、また、3D 計算ではあるけど、3D 計算というのはもともと「難しい数学が不要」で、四則演算と、ちょっとの sin, cos ができれば、できるものなんです。
上の 3D の回転は、下のプログラムでできていますが、ざっとみても、Three.js などの 3D のライブラリにはアクセスしていないし、行列計算も行っていません。
立方体とネコを 3D 回転するプログラム:
test2[20180202-obj/Microsoft Excel]
class App {
constructor( canvas ) {
this.cc = canvas.getContext( "2d" );
this.cc.canvas.width = 512;
this.cc.canvas.height = 448;
this.timerId = null;
this.objectz = {
//====================cube
cube : { //unit: mm
type : 0, //normal
name : "cube",
close : true, //各面は最後に cc.closePath() を行うか
ccPropz : {
fillStyle : "rgba(250,250,100,0.5)",
strokeStyle : "black",
lineWidth : 1,
lineJoin : "round",
},
tens : [
{ x : -1, y : +1, z : -1 }, //0: 左上 手前
{ x : +1, y : +1, z : -1 }, //1: 右上 手前
{ x : +1, y : -1, z : -1 }, //2: 右下 手前
{ x : -1, y : -1, z : -1 }, //3: 左下 手前
{ x : -1, y : +1, z : +1 }, //4: 左上 奥
{ x : +1, y : +1, z : +1 }, //5: 右上 奥
{ x : +1, y : -1, z : +1 }, //6: 右下 奥
{ x : -1, y : -1, z : +1 }, //7: 左下 奥
],
center : { x : 0, y : 0, z : 0 }, //tensが示すモデルの、中心座標
mens : [
[ 0, 1, 2, 3 ], //正面
[ 0, 4, 5, 1 ], //天面
[ 0, 3, 7, 4 ], //左面
[ 2, 6, 7, 3 ], //下面
[ 4, 7, 6, 5 ], //背面
[ 1, 5, 6, 2 ], //右面
],
size : 700,
pos : { x : -800, y : 0, z : 6000 },
rotation : { x : 0, y : 0, z : 0 },
},
//====================cat
bezier : {
type : 1, //bezier
name : "neko",
close : true, //各面は最後に cc.closePath() を行うか
ccPropz : {
fillStyle : "pink",
strokeStyle : "rgb(200,50,150)",
lineWidth : 4,
lineJoin : "round",
},
tens : [
{ x : 478, y : 165, z : 0 }, //1
{ x : 506, y : 162, z : 0 }, //2
{ x : 535, y : 162, z : 0 }, //3
{ x : 563, y : 165, z : 0 }, //4
{ x : 573, y : 147, z : 0 }, //5
{ x : 578, y : 129, z : 0 }, //6
{ x : 592, y : 111, z : 0 }, //7
{ x : 664, y : 206, z : 0 }, //8
{ x : 666, y : 339, z : 0 }, //9
{ x : 521, y : 340, z : 0 }, //10
{ x : 381, y : 339, z : 0 }, //11
{ x : 380, y : 206, z : 0 }, //12
{ x : 450, y : 111, z : 0 }, //13
{ x : 464, y : 130, z : 0 }, //14
{ x : 469, y : 147, z : 0 }, //15
{ x : 478, y : 165, z : 0 }, //16
],
center : { x : 478, y : 230, z : 0 }, //tensが示すモデルの、中心座標
mens : [
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ],
],
size : 6,
pos : { x : 800, y : 0, z : 6000 },
rotation : { x : 0, y : 0, z : 0 },
},
//====================
}//objects{}
//カメラ
this.cam = {
s : 50, //焦点距離(何mmレンズ)
zoom : 14, //引き伸ばし
}
}//constructor()
start() {
//動作を開始する
//check. すでに動作中
if( this.timerId ) return;
this.tmBak = 0;
this.frame( 0 );
}
stop() {
//動作を停止する
//check. すでに停止中
if( this.timerId == null ) return;
cancelAnimationFrame( this.timerId );
this.timerId = null;
}
frame( tm ) {
if( tm - this.tmBak >= 100 ) { //ミリ秒ごとに
this.tmBak = tm;
//各オブジェクトを回転
let add = 0.01;
for( let name in this.objectz ) {
let object = this.objectz[ name ];
object.rotation.x += add;
object.rotation.y += add;
object.rotation.z += add;
}
this.draw( this.cc );
}
this.timerId = requestAnimationFrame( this.frame.bind( this ) );
}
draw( cc ) {
cc.clearRect( 0, 0, this.cc.canvas.width, this.cc.canvas.height );
cc.save();
cc.translate( this.cc.canvas.width / 2, this.cc.canvas.height / 2 );
cc.scale( 1, -1 );
//各オブジェクトについて
for( let name in this.objectz ) {
let object = this.objectz[ name ];
for( let propName in object.ccPropz ) {
cc[ propName ] = object.ccPropz[ propName ];
}
let bezierPs = new Array();
//1オブジェクトを構成する各面について
for( let i = 0; i < object.mens.length; i++ ) {
let men = object.mens[ i ];
cc.beginPath();
//1面を構成する各点について
for( let j = 0; j < men.length; j++ ) {
let tenIdx = men[ j ];
let ten = object.tens[ tenIdx ];
//ローカル座標
let x = ( ten.x - object.center.x ) * object.size;
let y = ( ten.y - object.center.y ) * object.size;
let z = ( ten.z - object.center.z ) * object.size;
//x, y, z軸回転(自転)
if( object.rotation.x ) {
let res = this.rotate( z, y, object.rotation.x );
z = res.x;
y = res.y;
}
if( object.rotation.y ) {
let res = this.rotate( x, z, object.rotation.y );
x = res.x;
z = res.y;
}
if( object.rotation.z ) {
let res = this.rotate( x, y, object.rotation.z );
x = res.x;
y = res.y;
}
//ワールド座標へ移動
x += object.pos.x;
y += object.pos.y;
z += object.pos.z;
//3D -> 2D
let h = x * ( this.cam.s / z ) * this.cam.zoom;
let v = y * ( this.cam.s / z ) * this.cam.zoom;
//描画
if( j == 0 ) {
cc.moveTo( h, v ); //最初
} else {
//2回目以降
if( object.type == 0 ) {
//cube
cc.lineTo( h, v );
} else {
//bezier
bezierPs.push( h, v );
//check. bezierCurveTo() の引数がそろった
if( bezierPs.length == 6 ) {
cc.bezierCurveTo( ...bezierPs );
bezierPs.length = 0;
}
}
}
}//for j 各点
if( object.close ) cc.closePath();
cc.fill();
cc.stroke();
}//for i 各面
}//for name 各オブジェクト
cc.restore();
}//draw()
//数学 回転計算
rotate( x, y, theta2 ) {
let theta1 = Math.atan2( y, x );
let hankei = Math.sqrt( x * x + y * y );
return {
x : Math.cos( theta1 + theta2 ) * hankei,
y : Math.sin( theta1 + theta2 ) * hankei,
}
}//rotate()
}//App
データの部分を見てしまうと難しそうに見えるかもしれませんが、このプログラムの 3D としての中心的な計算は、181行と、182行の
//3D -> 2D
let h = x * ( this.cam.s / z ) * this.cam.zoom;
let v = y * ( this.cam.s / z ) * this.cam.zoom;
この計算です。
3D 計算というのは、このように実は四則演算だけで描画されています。
で、肝心のベジェ曲線のデータ形式ですが、他の 3D のオブジェクトと同じように、tens という配列の中にベジェのデータを入れるのが良いかなと思います。
私は最近、Excel 上の図形を JavaScript で表示することを考えています。
Excel 上の図形のデータを取り出して、JavaScript で読めるテキストファイルにおさめるだけなら、まだ簡単でしたが、Excel は楕円などの図形を、長半径と短半径、楕円の座標、というようなおおざっぱな情報で表現しているので、JavaScript で 3D 回転などを行いたい場合は、ベジェ曲線に変換しなければなりません。
そこで、今日は、「楕円」を「ベジェ曲線」に変換するプログラムのお話をします。
▼「楕円」を「ベジェ曲線」に変換
▼ベジェ曲線とはハンドルを動かして形を自由に変えられる図形です。 | ▼図形を 3D 回転させる |
変換プログラムは大変だったんですが、何とかできました。
JavaScript で楕円を描く際の標準のメソッドであるellipse() の描画(オレンジ太線)と、私の自作のベジェ曲線による楕円の描画(青い細線)が一致している様子を下のフォームをいじって確認できます。
startAngle: | ||||
endAngle: |
通常、JavaScript で楕円を描画するときは、以下のようにします。
cc.beginPath();
cc.ellipse( 0, 0, a, b, 0, startAngle, endAngle, isReverse );
cc.stroke();
この標準の記述となるべく同じ記述になるように(わかりやすくするために)、プログラムを工夫しました。
以下は、今回作成した変換プログラム(関数)を利用している様子です。
let array = ellipse2bezierPoints( 0, 0, a, b, startAngle, endAngle, isReverse );
cc.beginPath();
drawBezierPoints( cc, array );
cc.stroke();
この、ellipse2bezierPoints() が楕円情報をベジェデータに変換する関数で、drawBezierPoints() がそのベジェデータを画面に描画する関数です。
この2つの関数を少し詳しく紹介します。
ellipse2bezierPoints() は、標準の cc.ellipse() と同じような引数を取りますが、楕円は描画せずに、「ベジェ曲線のデータ」を作成して返します。
やや長めの関数になっており、行っている処理は、少し複雑になっています。
ellipse2bezierPoints() 関数の流れ:
ellipse2bezierPoints() は以上のような流れで、楕円をベジェデータに変換しています。
実際のプログラムは下記です。
上記1~5の説明の出だしをプログラムの中のコメントで書いてあるので、上記流れの説明との対応関係がわかると思います。
楕円→ベジェデータ変換の ellipse2bezierPoints() のプログラムリスト:
function ellipse2bezierPoints( x, y, radiusX, radiusY, startAngle, endAngle, isReverse ) {
//======================================================
//1.楕円をベジェ曲線で描くときは、数学のグラフを座標軸で4分割したときの「象限」単位で描かれる。…
let ellipseBeziers = [
[ //右下の象限の最初のベジェ(完全な4半円)
{ x : radiusX, y : 0 },
{ x : radiusX, y : .552 * radiusY },
{ x : .552 * radiusX, y : radiusY },
{ x : 0, y : radiusY },
],
[ //左下の象限の最初のベジェ(完全な4半円)
{ x : 0, y : radiusY },
{ x : -.552 * radiusX, y : radiusY },
{ x : -radiusX, y : .552 * radiusY },
{ x : -radiusX, y : 0 },
],
[ //左上の象限の最初のベジェ(完全な4半円)
{ x : -radiusX, y : 0 },
{ x : -radiusX, y : -.552 * radiusY },
{ x : -.552 * radiusX, y : -radiusY },
{ x : 0, y : -radiusY },
],
[ //右上の象限の最初のベジェ(完全な4半円)
{ x : 0, y : -radiusY },
{ x : .552 * radiusX, y : -radiusY },
{ x : radiusX, y : -.552 * radiusY },
{ x : radiusX, y : 0 },
],
];
let beziers = new Array();
let adjust = isReverse ? norm( endAngle ) : norm( startAngle );
let shogenBak = -1;
let shogenCount = 0;
let tail;
//下記 //◆ で示す部分の for のパラメーター
let diffAngle;
let pi360 = Math.PI * 2;
if( endAngle > startAngle ) {
diffAngle = endAngle - startAngle;
if( isReverse ) diffAngle = pi360 - diffAngle % pi360;
} else if( startAngle > endAngle ) {
diffAngle = startAngle - endAngle;
if( ! isReverse ) diffAngle = pi360 - diffAngle % pi360;
} else {
//startAngle == endAngle
diffAngle = 0;
}
let iStep = 0.1;
let aStep = isReverse ? -iStep : iStep;
//◆ 角度 a は四半円分移動する。(この角度 a は象限を検出するためにだけ利用している)
for( let i = 0, a = startAngle; i < diffAngle; i += iStep, a += aStep ) {
let shogen = Math.floor( norm( a ) / ( Math.PI / 2 ) ) % 4;
//check.
if( shogen == shogenBak ) continue;
//ここで新しい象限が検出された
//======================================================
//2.とりあえず、その1つの象限で描画される楕円の一部(4半円)を描くベジェ曲線を得る。…
let isSuddenly = false; //その象限に入った時点ですでに対象範囲内だったというフラグ
let changeCount = 0; //その象限内で、対象範囲の開始・終了が切り替わった回数
let areaNow = false; //現在対象範囲であるというフラグ
let quarterBeziers = new Array(); //象限内に作成されたベジェ(個数は0個、1個、2個のいずれかで3個には決してならない)
let currentBezier = ellipseBeziers[ shogen ]; //現在加工中のベジェ
//tweak. 反時計回りの時は、ベジェパラメーターを逆並びにする。
if( isReverse ) currentBezier = currentBezier.reverse();
//======================================================
//3.ある変数 t を 0 から 1 まで 0.01 ずつ進めると、1つのベジェ曲線を形作る約 100 個…
//その象限についてtを0から1まで変化させる。楕円の曲線を形作る点 p が得られる。(※currentBezierそのものから点pは得られない)
for( let t = 0; t < 1; t += 0.01 ) {
let bo = getBezierObject( t, currentBezier );
//boのメンバ
//bo.result t に対応する、ベジェ曲線上の点
//bo.roots bo.result を算出する際にできる、bo.result を頂点としたツリーの左側面と右側面
//bo.pointsByT bo.result を算出する際に使用する一時的なもの
//======================================================
//4.その「結果の点」を Math.atan2() の引数に入れて得られる角度は、描こうとする楕円の開始角度と…
let p = bo.result;
//その点の角度を得る
let rate = radiusX / radiusY;
let angle = norm( Math.atan2( p.y * rate, p.x ) - adjust ); // % ( Math.PI * 2 );
if( angle >= 0 && angle <= diffAngle ) {
if( ! areaNow ) {
//対象範囲に入った
//check. 初回の象限であり、その象限の最初である。(いきなり始まった分は末尾の端かもしれない)
if( shogenCount == 0 && t == 0 ) isSuddenly = true;
changeCount ++;
areaNow = true;
//check.
if( t == 0 ) continue; //初回はベジェ分割しない
//ベジェを分割
currentBezier = bo.roots[ 1 ]; //前ベジェは範囲外なので破棄し、後ベジェをカレントにする。
t = 0;
}
} else {
if( areaNow ) {
//対象範囲から出た
changeCount ++;
areaNow = false;
//ベジェを分割
quarterBeziers.push( bo.roots[ 0 ] );
currentBezier = bo.roots[ 1 ];
t = 0;
}
}
}//for t
//この時点で1つの象限を見た
//check. エリア内のまま象限を終えた
if( areaNow ) quarterBeziers.push( currentBezier );
//check. いきなり始まった分は末尾の端だった
if( isSuddenly && changeCount >= 2 ) tail = quarterBeziers.shift();
//この象限分のベジェを追加
beziers.push( ...quarterBeziers );
shogenBak = shogen;
shogenCount ++;
//check. 象限は4つ見ればよい
if( shogenCount == 4 ) break;//for i
}//for i, a
//check. 末尾の端
if( tail ) beziers.push( tail );
//ここで beziers は得られた。
//======================================================
//5.4象限分のベジェを作成したら、最後にその各ベジェを、1つの「ベジェ曲線のデータ」として…
//beziers を1つのベジェへ結合する
let bezierPoints = new Array();
let before;
for( let i = 0; i < beziers.length; i++ ) {
let bezier = beziers[ i ];
for( let j = 0; j < bezier.length; j++ ) {
let p = bezier[ j ];
//check. 同じ点はスキップ
if( i > 0 && p.x == before.x && p.y == before.y ) continue;
bezierPoints.push( p );
before = p;
}
}//for i
return bezierPoints;
}//ellipse2bezierPoints()
//角度から、余分な回転を削除し、角度が負の場合は正に直す。
function norm( angle ) {
angle = angle % ( Math.PI * 2 );
if( angle < 0 ) angle += Math.PI * 2;
return angle;
}
//ベジェの原理の「過程と結果」オブジェクトを得る
function getBezierObject( t, bo ) {
//check. 最初は bo は配列が渡される。
if( bo instanceof Array ) {
bo = { pointsByT : bo, roots : [ [], [] ] };
}
//check. 「ベジェの分割」時のための情報記録
bo.roots[ 0 ].push( bo.pointsByT[ 0 ] ); //"木構造のうち一番外側の点"(片側)
bo.roots[ 1 ].push( bo.pointsByT[ bo.pointsByT.length - 1 ] ); //"木構造のうち一番外側の点"(片側)
let newPointsByT = new Array();
for( let i = 0; i < bo.pointsByT.length - 1; i++ ) {
let sp = bo.pointsByT[ i ];
let ep = bo.pointsByT[ i + 1 ];
let lenX = ep.x - sp.x;
let lenY = ep.y - sp.y;
newPointsByT.push( {
x : lenX * t + sp.x,
y : lenY * t + sp.y
} );
}
bo.pointsByT = newPointsByT;
//再帰終了
if( bo.pointsByT.length == 1 ) {
//check. 「ベジェの分割」時のための情報記録
bo.roots[ 0 ].push( bo.pointsByT[ 0 ] );
bo.roots[ 1 ].push( bo.pointsByT[ 0 ] );
//check.
//そのままだと両側から1点に向かう2つのベジェとなっているので、
//片方のベジェ([1])は点から端に向かうベジェに直す
bo.roots[ 1 ] = bo.roots[ 1 ].reverse();
bo.result = bo.pointsByT[ 0 ];
return bo;
} else
return getBezierObject( t, bo );
}//getBezierObject()
変換で作成された「ベジェ曲線のデータ」をもとに、cc.beziercurveTo() メソッドを使ってベジェ曲線を描画します。
「ベジェ曲線のデータ」は1次元配列ですが、最初に描画開始の点、その次から cc.bezierCurveTo() に渡す3つの点が cc.bezierCurveTo() の回数分繰り返される、というようなフォーマットになっています。
描画開始の 点の x, y 座標 |
cc.bezierCurveTo() に 渡す点1の x, y 座標 |
cc.bezierCurveTo() に 渡す点2の x, y 座標 |
cc.bezierCurveTo() に 渡す点3の x, y 座標 |
cc.bezierCurveTo() に 渡す点1の x, y 座標 |
cc.bezierCurveTo() に 渡す点2の x, y 座標 |
cc.bezierCurveTo() に 渡す点3の x, y 座標 |
cc.bezierCurveTo() に 渡す点1の x, y 座標 |
cc.bezierCurveTo() に 渡す点2の x, y 座標 |
cc.bezierCurveTo() に 渡す点3の x, y 座標 |
cc.bezierCurveTo() に 渡す点1の x, y 座標 |
・ ・ ・ つづく |
ベジェデータ描画の drawBezierPoints() のプログラムリスト:
test2[20180202-obj/Microsoft Excel]
function drawBezierPoints( cc, bezierPoints ) {
//check.
if( bezierPoints.length == 0 ) return;
cc.moveTo( bezierPoints[ 0 ].x, bezierPoints[ 0 ].y );
for( let i = 1; i < bezierPoints.length; i += 3 ) {
let p1 = bezierPoints[ i ];
let p2 = bezierPoints[ i + 1 ];
let p3 = bezierPoints[ i + 2 ];
cc.bezierCurveTo( p1.x, p1.y, p2.x, p2.y, p3.x, p3.y );
}
}//drawBezierPoints()
この関数はベジェのデータ・フォーマットの通りに点1~3を取り出して、bezierCurveTo() を行う内容になっています。
cc.bezierCurveTo() は下図のようなメソッドです。
この bezierCurveTo() に渡す各点を、事前に 3D 計算してから bezierCurveTo() に渡してやると、ベジェ曲線が 3D 空間に描かれます。
このヤフオクの入札1件、私ですねぇ。
前回からのつづきで、
>だからこのあと、楕円をベジェのハンドルで表現する作業(楕円→ベジェの変換)をやらなければなりません。
ということで、「楕円をベジェ曲線に変換する」というのを現在行っています。
下図は、
赤い点が、「楕円を描く式」で描いた楕円。
緑の太い線が、「JavaScript のビルトイン関数(最初から用意されている関数)」で描いた楕円の一部。
そして、オレンジ色の細い線が「ベジェの計算」で描いた同じ楕円の一部です。
ちゃんとベジェで描くことが出来ましたが、結構大変でした。
先月7/22に、同題名の記事を書きましたが、その中の図がまだ間違っていることに気付いて、今日になって修正をしました。
下図は修正した図です。
詳しくは、同記事へ飛んでください。
下図の左が Excel の画面、右がインターネットブラウザの画面です。
Excel VBA により、Excel シート上の図形が .js ファイルへ「ドローデータ」として保存されます。
「ドロー」とは点の位置や、線の長さ、曲線の曲がり具合などを数値として示した画像データのことです。
その .js をデータとして JavaScript で読み取り、データの通りに描画したものが上図の右側というわけです。赤丸急上昇
Excel で作成できる図形には種類があり、
の3種類が、大まかですが あります。
この 1 番と 2 番は「データとして何ら問題ない」のですが、今非常に困っているのが、3 番の「点を動かすと形が変わる図形」です。
▼黄色い「点」、つまり黄色い「◆」のある図形は、「◆」を動かすとその形を変えられる。
このタイプの図形は、「◆」の位置情報はデータとして読めるのですが、かんじんの「形のデータ」がどこにもないんです。
たとえば、上図の月なら、月を満ち掛けさせる「◆」の位置情報はあるけど、かんじんの月の形のデータがナイ!
星を太らせたりやせさせたりする「◆」の位置情報はあるけど、かんじんの星の形のデータがナイ!
▼これら小さな■で示される、「形のデータ」が VBA 上にナイ~! | |
それから、すべての図形が持っている「AutoShapeType」というプロパティを、たとえば msoMoonShape という数値から、msoStarShape という数値へ VBA で「変更するだけ」で、月だったものが星へ、一瞬にして切り替わる! AutoShapeType に代入するだけで不思議と変わる!
それで もしかしてと思いました、
つまり(たぶんですが)、
「msoMoonShape なら、それを描く専用の関数があり、その中で月を描いてる」
「msoStarShape ならそれを描く専用の関数があり、その中で星を描いてる」
…となっていて、つまり平たく言うと、形を描くところは「ネイティブになっている」、ということのようです。
(ネイティブ:Excel 内部の機械語の状態でしか存在していない)
ベジェのデータさえあれば良いので、月や星を「フリーフォーム」(ベジェデータだけで構成される)タイプの図形に変換する VBA のメソッドはないかなと思って探したんですが、ありませんでした。
その時点で私のこの「Excel 図形 → JavaScript 変換のプログラム」は、とても困難になってしまう、ということが確定してしまうんです。
”してしまう” じゃなくて、確定しました。
それで、今回一番最初の図で示した通り、Excel の「月の満ち欠け」 が JavaScript で再現されているんですが、それはとても大変でした。
まぁ、後から気付いたんですが、JavaScript で再現できても、その図形を JavaScript で 3D 回転させたい場合、「◆」の位置をベースにした上記の図形の描き方だと、ダメ(正しく3D回転できない)なんじゃないかなぁと。
だからこのあと、楕円をベジェのハンドルで表現する作業(楕円→ベジェの変換)をやらなければなりません。
「◆」を持った図形は Excel には他にもたくさんありますが、それら1つ1つ調査したりはできないので、「顔の眉毛でよく使っている月図形」のように、実際に絵を描くときに使っている図形に限る必要があります。
おそなえものを買ってきました。(左写真)
おそなえものを飾る準備はなかったので、誰かが退職時に私にくれた贈り物の小タオルで飾りました。(右写真)
→ → → |
ご先祖様には子供もいるんじゃないか、と思ってお菓子も付けました。
だから、私は世界の必要なインターネット(医学的に生命維持がネットの機能とつながっているとか、科学技術研究とか)だけを選択的に残して、不要なインターネットをすべて止めてしまいたいです。
ネットのない1980年代、本屋に行くと まっさきに「コンピューター」の棚に直行して、立ち読みを続けていたあのころが一番良かったと思います。
この人類の歴史の中で、今 これからそれ(インターネットを選択的に止める)が起こっても、特に不思議なことではなく、「人類は英断をしたな、よくそんなことが実現できたな」と後世の人たちは思うのではと思います。
それとも「あのときインターネットを止めなければ…」と悔やむのでしょうか。
上記の1つ1つを良い方向にもっていく具体的なものが見えれば、インターネットも認めても良いと思います。(下から2番目に法律を作ったように)
でも上記のように簡単にリストアップできて、それで効果的な対処もあまりできずに、「使っていたい」っていうのはホントにそれで良いんでしょうか。
前の記事に引き続いて、Excel 図形の JavaScript への変換のお話です。
グループ化された図形と、複雑なベジェ曲線の図形に対応しました。
まだ、いろいろ対応しなきゃいけない図形があります。
グラデーションとかも絵を描くとき、ときどき使うから、それも対応しなきゃならないです。
結構昔から「Excel で作成した図形を、JavaScript のデータへ変換できないか?」と思ってきました。
それで最近、Excel の VBA 言語を使って、取り組み始めました。
今日はやっと下図のように Excel の図形(左)を、JavaScript のデータにして CANVAS で描画(右)できるようになりました。
とりあえず、直線だけの図のみで、曲線ありの図はまだこれからです。
VBA はとにかく「くせ」だらけの環境なので、プログラミングするのが大変です。
(訪問者のどんなニーズと この記事がつながるか)